#include "render_ruler.h"
#include "../utils/kutils.h"
#include "qbe/src/layout/layout.hpp"
#include "qlib/utils/font.h"


namespace qbe::utils::TempRender {
std::vector<qlib::Vec2d> get_rule_lines(qlib::Vec2d p1, qlib::Vec2d p2, double step) {
  // 绘制区域
  auto box_x_min = 0;
  auto box_y_min = 100;
  auto box_x_max = 0;
  auto box_y_max = 100;

  // // 步长
  // double step = 10;
  double angle = auxiliary::angle_direction(p1, p2);
  double cal_angle = 0;
  double quadrant = 1;
  qlib::Vec2d start_pos, end_pos;
  // 1象限
  if (angle >= 0 && angle <= M_PI / 2) {
    cal_angle = angle + M_PI / 2;
    quadrant = angle == 0 ? 4 : 1;
  }
  // 2象限
  if (angle > M_PI / 2 && angle <= M_PI) {
    cal_angle = angle - M_PI / 2;
    quadrant = 2;
  }
  // 3象限
  if (angle > M_PI && angle <= (M_PI * 3) / 2) {
    cal_angle = angle - M_PI / 2;
    quadrant = 3;
  }
  // 4象限
  if (angle > (M_PI * 3) / 2 && angle <= M_PI * 2) {
    cal_angle = angle + M_PI / 2;
    quadrant = 4;
  }
  double dx = p2.x - p1.x;
  double dy = p2.y - p1.y;
  double len = sqrt(dx * dx + dy * dy);
  double n = floor(len / step);
  n = n < 1 ? 1 : n;
  double x_step = dx / n;
  double y_step = dy / n;

  std::vector<qlib::Vec2d> lines;
  // 绘制起点->终点
  lines.push_back(p1);
  lines.push_back(p2);

  // 绘制中间视图区域内刻度
  std::vector<qlib::Vec2d> line;
  bool find_left = false;
  int txt = 0;
  for (int i = 0; i < n; i++) {
    // 绘制刻度线和刻度值
    qlib::Vec2d p{p1.x + i * x_step, p1.y + i * y_step};
    if (i % 5 == 0) {
      line = auxiliary::pointExtendToLine(p, cal_angle, 15);
      txt = i * step;
    } else {
      line = auxiliary::pointExtendToLine(p, cal_angle, 5);
    }
    lines.push_back(line[0]);
    lines.push_back(line[1]);
    if (i == 0) {
      start_pos = line[1];
    }
  }
  // 终点刻度
  line = auxiliary::pointExtendToLine(p2, cal_angle, 15);
  lines.push_back(line[0]);
  lines.push_back(line[1]);

  end_pos = line[1];
  return lines;
};
RenderRuler::RenderRuler(vsg::ref_ptr<vsg::Options> options, std::vector<qlib::Ruler::s_ptr> rulers) : m_rulers(rulers) {
  switchObject = vsg::Switch::create();
  transform = vsg::MatrixTransform::create();
  switchObject->addChild(true, transform);

  std::vector<Mesh2D> meshs;
  for (auto i : m_rulers) {
    vsg::dvec4 start(i->start.x, i->start.y, 0.0, 1.0);
    start = start * m;
    vsg::dvec4 end(i->end.x, i->end.y, 0.0, 1.0);
    end = end * m;
    auto lines = get_rule_lines(qlib::Vec2d(start.x, start.y), qlib::Vec2d(end.x, end.y), m_step);
    auto mesh = Mesh2D();
    auto vertices = vsg::vec2Array::create(lines.size());
    auto indices = vsg::uintArray::create(lines.size());
    for (uint32_t i = 0; i < lines.size(); i++) {
      (*vertices)[i] = {float(lines[i].x), float(lines[i].y)};
      (*indices)[i] = i;
    }
    mesh.vertices = vertices;
    mesh.indices = indices;
    meshs.push_back(mesh);
  }
  Mesh2D merge_result;
  mesh_merge(meshs, merge_result);
  LineShaderMaterial2D material{Line_Uniform{vsg::vec4(1.0, 0.0, 0.0, 1.0), vsg::vec2(1316.0, 847.0), 100.0, 70.0, true},
                                "shaders/cell/line.vert.spv", "shaders/cell/line.frag.spv"};

  line_node = LineMeshNode::create(options, qlib::Tag{0, 0}, merge_result, material, VkPrimitiveTopology::VK_PRIMITIVE_TOPOLOGY_LINE_LIST);
  transform->addChild(line_node);
}

RenderRuler ::~RenderRuler() {}

void RenderRuler::setLayerType(vsg::vec4 color, std::string line_type) {
  line_node->setLayerType(color, line_type);
}

void RenderRuler::updateData(std::vector<qlib::Ruler::s_ptr> rulers) {
  if (rulers.empty())
    return;
  m_rulers = rulers;
  std::vector<Mesh2D> meshs;
  for (auto i : m_rulers) {
    vsg::dvec4 start(i->start.x, i->start.y, 0.0, 1.0);
    start = m * start;
    vsg::dvec4 end(i->end.x, i->end.y, 0.0, 1.0);
    end = m * end;
    auto lines = get_rule_lines(qlib::Vec2d(start.x, start.y), qlib::Vec2d(end.x, end.y), m_step);
    {
      auto text = qlib::get_text("0", qlib::Vec2d(start.x, start.y), 30, 0, qlib::Anchor::SW);
      lines.insert(lines.end(), text.begin(), text.end());
    }
    {
      auto dis = i->start.distance(i->end);
      auto text = qlib::get_text(QString::number(dis, 'f', 6).toStdString(), qlib::Vec2d(end.x, end.y), 30, 0, qlib::Anchor::SW);
      lines.insert(lines.end(), text.begin(), text.end());
    }
    auto mesh = Mesh2D();
    auto vertices = vsg::vec2Array::create(lines.size());
    auto indices = vsg::uintArray::create(lines.size());
    for (uint32_t i = 0; i < lines.size(); i++) {
      (*vertices)[i] = {float(lines[i].x), float(lines[i].y)};
      (*indices)[i] = i;
    }
    mesh.vertices = vertices;
    mesh.indices = indices;
    meshs.push_back(mesh);
  }
  Mesh2D merge_result;
  mesh_merge(meshs, merge_result);
  line_node->mesh = merge_result;
  line_node->update();
}

void RenderRuler::setShowHide(bool is_show) {
  switchObject->setAllChildren(is_show);
}

}  // namespace qbe::utils::TempRender